/*
 * AddRelationDialog.java
 *
 * Created on Sobota, 2008, január 12, 17:41
 */
package eu.easyedu.dictionary.gui;

import eu.easyedu.dictionary.api.model.Dictionary;
import eu.easyedu.dictionary.api.model.Language;
import eu.easyedu.dictionary.api.model.Relationship;
import eu.easyedu.dictionary.api.model.Word;
import eu.easyedu.dictionary.api.model.WordRelationship;
import eu.easyedu.dictionary.api.model.WordType;
import eu.easyedu.dictionary.api.nservice.spi.DictionaryService;
import eu.easyedu.dictionary.api.nservice.spi.WordBookService;
import eu.easyedu.dictionary.gui.resources.Bundle;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import org.openide.util.Lookup;

/**
 *
 * @author  hlavki
 */
public class AddRelationDialog extends javax.swing.JDialog {

    private static final long serialVersionUID = 1L;
    private static final Logger log = Logger.getLogger(AddRelationDialog.class.getName());
    private static final Relationship DEFAULT_RELATIONSHIP = Relationship.TRANSLATION;
    private DictionaryService dictService;
    private WordBookService wbService;
    private Dictionary dictionary;
    private List<Language> languages;
    private List<WordPanel> relationships;

    private enum PanelHighlight {

        OK, WRONG
    }

    /** Creates new form AddRelationDialog */
    public AddRelationDialog(java.awt.Frame parent, boolean modal, Dictionary dictionary, Word word) {
        super(parent, modal);
        this.dictionary = dictionary;
        this.wbService = Lookup.getDefault().lookup(WordBookService.class);
        this.languages = wbService.getAllLanguages(dictionary);
        initComponents();
        relationships = new ArrayList<WordPanel>();
        defaultWordPanel.addWordTypeComboBoxActionListener(new java.awt.event.ActionListener() {

            public void actionPerformed(java.awt.event.ActionEvent evt) {
                defaultWordTextFieldActionPerformed(evt);
            }
        });
        defaultWordPanel.setWord(word);
        addRelationshipsForAllLanguages(DEFAULT_RELATIONSHIP);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        relationsPanel = new javax.swing.JPanel();
        defaultWordPanel = new eu.easyedu.dictionary.gui.WordPanel();
        buttonPanel = new javax.swing.JPanel();
        saveButton = new javax.swing.JButton();
        cancelButton = new javax.swing.JButton();
        infoLabel = new javax.swing.JLabel();
        jPanel1 = new javax.swing.JPanel();
        addRelationButton = new javax.swing.JButton();
        removeRelationButton = new javax.swing.JButton();
        validateButton = new javax.swing.JButton();
        relationshipComboBox = new javax.swing.JComboBox();
        createWordsCheckBox = new javax.swing.JCheckBox();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

        relationsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), Bundle.getMessage("AddRelationDialog.relationsPanel.border.title"))); // NOI18N
        relationsPanel.setLayout(new javax.swing.BoxLayout(relationsPanel, javax.swing.BoxLayout.PAGE_AXIS));

        defaultWordPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), Bundle.getMessage("AddRelationDialog.defaultWordPanel.border.title"))); // NOI18N
        defaultWordPanel.setLanguageComboBoxModel(getLanguageComboBoxModel());
        defaultWordPanel.setWordTypeComboBoxModel(getWordTypeComboBoxModel());

        saveButton.setText(Bundle.getMessage("AddRelationDialog.saveButton.text")); // NOI18N
        saveButton.setPreferredSize(new java.awt.Dimension(70, 24));
        saveButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveButtonActionPerformed(evt);
            }
        });
        buttonPanel.add(saveButton);

        cancelButton.setText(Bundle.getMessage("AddRelationDialog.cancelButton.text")); // NOI18N
        cancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelButtonActionPerformed(evt);
            }
        });
        buttonPanel.add(cancelButton);

        infoLabel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(204, 204, 204)));

        addRelationButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/eu/easyedu/dictionary/gui/resources/icons/list-add.png"))); // NOI18N
        addRelationButton.setToolTipText(Bundle.getMessage("AddRelationDialog.addRelationButton.toolTipText")); // NOI18N
        addRelationButton.setPreferredSize(new java.awt.Dimension(23, 23));
        addRelationButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addRelationButtonActionPerformed(evt);
            }
        });

        removeRelationButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/eu/easyedu/dictionary/gui/resources/icons/list-remove.png"))); // NOI18N
        removeRelationButton.setToolTipText(Bundle.getMessage("AddRelationDialog.removeRelationButton.toolTipText")); // NOI18N
        removeRelationButton.setPreferredSize(new java.awt.Dimension(23, 23));
        removeRelationButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removeRelationButtonActionPerformed(evt);
            }
        });

        validateButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/eu/easyedu/dictionary/gui/resources/icons/refresh.png"))); // NOI18N
        validateButton.setToolTipText(Bundle.getMessage("AddRelationDialog.validateButton.toolTipText")); // NOI18N
        validateButton.setPreferredSize(new java.awt.Dimension(23, 23));
        validateButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                validateButtonActionPerformed(evt);
            }
        });

        relationshipComboBox.setModel(getRelationshipComboBoxModel());
        relationshipComboBox.setSelectedItem(DEFAULT_RELATIONSHIP);
        relationshipComboBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                relationshipComboBoxActionPerformed(evt);
            }
        });

        createWordsCheckBox.setSelected(true);
        createWordsCheckBox.setText(Bundle.getMessage("AddRelationDialog.createWordsCheckBox.text")); // NOI18N

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 420, Short.MAX_VALUE)
            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel1Layout.createSequentialGroup()
                    .addContainerGap()
                    .addComponent(addRelationButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(removeRelationButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(validateButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(relationshipComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 136, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(createWordsCheckBox)
                    .addContainerGap(75, Short.MAX_VALUE)))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 42, Short.MAX_VALUE)
            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel1Layout.createSequentialGroup()
                    .addGap(6, 6, 6)
                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(relationshipComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(createWordsCheckBox))
                        .addComponent(addRelationButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(removeRelationButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(validateButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(defaultWordPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 420, Short.MAX_VALUE)
                    .addComponent(buttonPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 420, Short.MAX_VALUE)
                    .addComponent(relationsPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 420, Short.MAX_VALUE)
                    .addComponent(infoLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 420, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(defaultWordPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(relationsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 63, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(infoLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(12, 12, 12)
                .addComponent(buttonPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 34, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents
    private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveButtonActionPerformed
        if (validateRelationships() || createWordsCheckBox.isSelected()) {
            Word defaultWord = defaultWordPanel.getWord();
            if (!defaultWord.exists()) {
                defaultWordPanel.setWord(wbService.addWord(dictionary, defaultWord, getWordRelationships()));
                log.info("Word successfully inserted with ID: " + defaultWordPanel.getWord().getId());
            } else {
                wbService.addRelationships(dictionary, getWordRelationships());
            }
            setVisible(false);
        }
    }//GEN-LAST:event_saveButtonActionPerformed

    private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
        setVisible(false);
    }//GEN-LAST:event_cancelButtonActionPerformed

    private void addRelationButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addRelationButtonActionPerformed
        addRelationship((Relationship) relationshipComboBox.getSelectedItem());
}//GEN-LAST:event_addRelationButtonActionPerformed

    private void removeRelationButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeRelationButtonActionPerformed
        removeLastRelationship();
}//GEN-LAST:event_removeRelationButtonActionPerformed

    private void validateButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_validateButtonActionPerformed
        validateRelationships();
    }//GEN-LAST:event_validateButtonActionPerformed

    private void relationshipComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_relationshipComboBoxActionPerformed
        WordPanel lastRelationship = relationships.get(relationships.size() - 1);
        lastRelationship.setRelationship((Relationship)relationshipComboBox.getSelectedItem());
    }//GEN-LAST:event_relationshipComboBoxActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton addRelationButton;
    private javax.swing.JPanel buttonPanel;
    private javax.swing.JButton cancelButton;
    private javax.swing.JCheckBox createWordsCheckBox;
    private eu.easyedu.dictionary.gui.WordPanel defaultWordPanel;
    private javax.swing.JLabel infoLabel;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel relationsPanel;
    private javax.swing.JComboBox relationshipComboBox;
    private javax.swing.JButton removeRelationButton;
    private javax.swing.JButton saveButton;
    private javax.swing.JButton validateButton;
    // End of variables declaration//GEN-END:variables

    private ComboBoxModel getLanguageComboBoxModel() {
        return new DefaultComboBoxModel(languages.toArray());
    }

    private ComboBoxModel getWordTypeComboBoxModel() {
        return new DefaultComboBoxModel(WordType.values());
    }

    public void addRelationshipsForAllLanguages(Relationship relationship) {
        Language defaultLanguage = defaultWordPanel.getWord().getLanguage();
        for (Language lang : languages) {
            if (!lang.equals(defaultLanguage)) {
                addRelationship(relationship, lang);
            }
        }
    }

    public void addRelationship(Relationship relationship) {
        Language defaultLanguage = defaultWordPanel.getWord().getLanguage();
        addRelationship(relationship, defaultLanguage);
    }

    public void addRelationship(Relationship relationship, Language language) {
        relationsPanel.setVisible(true);
        Word translationWord = new Word();
        Word defaultWord = defaultWordPanel.getWord();
        translationWord.setLanguage(language);
        if (defaultWord.exists()) {
            translationWord.setType(defaultWord.getType());
        }
        WordPanel translationPanel = new WordPanel(translationWord, relationship);
        translationPanel.setLanguageComboBoxModel(getLanguageComboBoxModel());
        translationPanel.setWordTypeComboBoxModel(getWordTypeComboBoxModel());
        relationships.add(translationPanel);
        relationsPanel.add(translationPanel);
        pack();
    }

    public void removeLastRelationship() {
        removeRelationPanel(relationships.size() - 1);
    }

    protected void removeRelationPanel(int index) {
        log.fine("Removing panel with index " + index);
        if (index >= 0 && index < relationships.size()) {
            WordPanel panel = relationships.get(index);
            relationsPanel.remove(panel);
            relationships.remove(panel);
            panel.setVisible(false);
            setSize(getWidth(), getHeight() - panel.getHeight());
            if (relationships.size() == 0) {
                relationsPanel.setVisible(false);
            }
            pack();
            relationsPanel.repaint();
        }
    }

    private final void defaultWordTextFieldActionPerformed(ActionEvent evt) {
        JComboBox cb = (JComboBox) evt.getSource();
        WordType selectedWordType = (WordType) cb.getSelectedItem();
        for (WordPanel panel : relationships) {
            panel.setWordType(selectedWordType);
        }
    }

    private final List<WordRelationship> getWordRelationships() {
        List<WordRelationship> result = new ArrayList<WordRelationship>();
        Word defaultWord = defaultWordPanel.getWord();
        for (WordPanel panel : relationships) {
            result.add(new WordRelationship(defaultWord, panel.getWord(), panel.getRelationship()));
        }
        return result;
    }

    private boolean validateRelationships() {
        clearValidation();
        int count = 0;
        for (WordPanel panel : relationships) {
            Word panelWord = panel.getWord();
            Word relatedWord = wbService.getWord(dictionary, panelWord.getWord(), panelWord.getLanguage());
            if (relatedWord == null) {
                setPanelHighlight(panel, PanelHighlight.WRONG);
                count++;
            } else {
                panel.setWord(relatedWord);
            }
        }
        if ("".equals(defaultWordPanel.getWord().getWord().trim())) {
            setPanelHighlight(defaultWordPanel, PanelHighlight.WRONG);
            count++;
        }
        repaint();
        if (count > 0) {
            infoLabel.setForeground(Color.RED);
            infoLabel.setText(Bundle.getMessage("AddWordDialog.validation.WRONG"));
        } else {
            infoLabel.setForeground(Color.BLACK);
            infoLabel.setText(Bundle.getMessage("AddWordDialog.validation.OK"));
        }
        return count == 0;
    }

    protected void clearValidation() {
        setPanelHighlight(defaultWordPanel, PanelHighlight.OK);
        for (WordPanel panel : relationships) {
            setPanelHighlight(panel, PanelHighlight.OK);
        }
    }

    private final void setPanelHighlight(WordPanel panel, PanelHighlight highlight) {
        switch (highlight) {
            case OK:
                panel.setBackground(new Color(238, 238, 238));
                break;
            case WRONG:
                panel.setBackground(new Color(252, 220, 220));
                break;
        }
    }

    protected final ComboBoxModel getRelationshipComboBoxModel() {
        return new DefaultComboBoxModel(Relationship.values());
    }
}
